library ieee;
use ieee.std_logic_1164.all;
use IEEE.NUMERIC_STD.all;
use work.typeDefinitions.all;

entity LinkRegister is
  port
    (
      clk, nReset : in  std_logic;
      -- Address to be locked
      lockAddr    : in  std_logic_vector(31 downto 0);
      -- WEN for lockAddr
      lockWEN     : in  std_logic;
      -- Operation on the bus (from other processor)
      busOp       : in  memBusOp;
      -- Address of data on the bus (from other processor)
      busAddr     : in  std_logic_vector(31 downto 0);
      -- Locked address output
      lockOut     : out std_logic_vector(31 downto 0)
      );
end LinkRegister;

architecture LinkRegister_arch of LinkRegister is

  signal lockReg               : std_logic_vector(31 downto 0);
  signal t_lockAddr, t_busAddr : std_logic_vector(31 downto 0);
  signal t_invalidate          : std_logic;

begin

  lockOut <= lockReg;

  t_lockAddr <= lockAddr(31 downto 3) & "000";
  t_busAddr  <= busAddr(31 downto 3) & "000";

  reg : process(clk, nReset, t_invalidate, lockReg, t_lockAddr, lockWEN)
  begin
    if(nReset = '0') then
      lockReg <= (others => '0');
    elsif(falling_edge(clk)) then  -- opposite clock edge as cache controller
      if(t_invalidate = '1') then
        lockReg <= (others => '0');
      else
        if(lockWEN = '1') then
          lockReg <= t_lockAddr;
        else
          lockReg <= lockReg;
        end if;
      end if;
    end if;
  end process;

  inv : process(t_busAddr, busOp, lockReg, t_lockAddr)
  begin
    t_invalidate <= '0';
    if(busOp = bus_RdX) then
      if(t_busAddr = t_lockAddr or t_busAddr = lockReg) then
        t_invalidate <= '1';
      end if;
    end if;
  end process;
  
end LinkRegister_arch;
